package org.walklink.common.util;

import com.caucho.hessian.io.HessianInput;
import com.caucho.hessian.io.HessianOutput;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.walklink.common.entity.DefaultTrackDto;
import org.walklink.common.entity.jvm.JvmTrackDto;
import org.walklink.common.enums.EventTypeEnum;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Objects;

/**
 * Hessian处理工具类
 *
 * @author lidishan
 */
public class HessianUtil {

    private static final Logger LOGGER = LoggerFactory.getLogger(HessianUtil.class);

    /**
     * Hessian实现序列化
     *
     * @param obj 待序列化对象
     * @return 序列化之后的byte数组
     */
    public static byte[] serialize(Object obj) {
        HessianOutput hessianOutput = null;
        try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
            // Hessian的序列化输出
            hessianOutput = new HessianOutput(byteArrayOutputStream);
            hessianOutput.writeObject(obj);
            return byteArrayOutputStream.toByteArray();
        } catch (IOException e) {
            LOGGER.error("[HessianUtil_serialize_error] Exception obj={}", obj, e);
        } finally {
            try {
                if (hessianOutput != null) {
                    hessianOutput.close();
                }
            } catch (IOException ex) {
                LOGGER.error("[HessianUtil_serialize_error] IOException close obj={}", obj, ex);
            }
        }
        return null;
    }

    /**
     * Hessian实现反序列化
     *
     * @param bytes 待反序列化byte数组
     * @param clazz class对象
     * @return 对象
     */
    public static <T> T deserialize(byte[] bytes, Class<T> clazz) {
        HessianInput hessianInput = null;
        try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes)) {
            // Hessian的反序列化读取对象
            hessianInput = new HessianInput(byteArrayInputStream);
            return clazz.cast(hessianInput.readObject());
        } catch (IOException e) {
            LOGGER.error("[HessianUtil_deserialize_error] IOException", e);
        } finally {
            try {
                if (hessianInput != null) {
                    hessianInput.close();
                }
            } catch (Exception e) {
                LOGGER.error("[HessianUtil_deserialize_error] IOException close", e);
            }
        }
        return null;
    }

    public static void main(String[] args) {
        JvmTrackDto allJvmInfo = JvmStackUtil.getAllJvmInfo();
        DefaultTrackDto<JvmTrackDto> obj = new DefaultTrackDto<>(EventTypeEnum.JVM_SYN, allJvmInfo);
        System.out.println(JsonUtil.silentObject2String(obj));
        byte[] serialize = HessianUtil.serialize(obj);
        System.out.println(serialize.toString());
        DefaultTrackDto deserialize = HessianUtil.deserialize(serialize, DefaultTrackDto.class);
        if (Objects.nonNull(deserialize)) {
            JvmTrackDto cast = (JvmTrackDto) deserialize.getData();
            System.out.println(JsonUtil.silentObject2String(cast));
        }
        System.out.println(JsonUtil.silentObject2String(deserialize));
        System.out.println(1);
    }

}
